#include <reg51.h>
#include "ds18b20.h"
#include <intrins.h>
#include "uart.h"

/**************** 新增延时函数实现 ****************/
void DS18B20_Delayus(unsigned int us)
{
    while (us--)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

//发送一位
void ds18b20_write_bit(unsigned char bits)
{ 
	unsigned char i;
	DS18B20_DQ = 0;
	i = 4;
	while (--i); //延时10us
	DS18B20_DQ = bits;
	i = 24;
	while (--i); //延时50us
	DS18B20_DQ = 1;
}

/**************** 写字节函数 ****************/
void DS18B20_WriteByte(unsigned char dat)
{
    unsigned char i;
    for (i = 0; i < 8; i++)
    {
        ds18b20_write_bit(dat & 0x01<<i);  // 低位先发
    }
}

//接收一位
unsigned char ds18b20_read_bit()
{ 
	unsigned char i;
	unsigned char bits;
	DS18B20_DQ = 0;
	i = 2;
	while (--i); //延时5us
	DS18B20_DQ = 1;
	i = 2;
	while (--i); //延时5us
	bits = DS18B20_DQ;
	i = 24;
	while (--i); //延时50us
	return bits;
}

/**************** 读字节函数 ****************/
unsigned char DS18B20_ReadByte(void)
{
    unsigned char i, dat = 0;
    for (i = 0; i < 8; i++)
    {
        if (ds18b20_read_bit())
        {
            dat |= 0x01 << i;
        }
    }
    return dat;
}

unsigned char DS18B20_Reset(void)
{
    unsigned char i;

    DS18B20_DQ = 1;
    DS18B20_DQ = 0;

    DS18B20_Delayus(480); // 480us复位脉冲
    DS18B20_DQ = 1;

    i = 0;
    while (DS18B20_DQ)
    {
        i++;
        if (i > 80)
            return 1; // 超时480us未响应，返回1
    }

    return 0; // 传感器响应，返回0
}

//转换温度
void ds18b20_ConvertT()
{
	DS18B20_Reset();
    // UART_SendString("write transform code~\r\n");
    DS18B20_Delayus(100);

	DS18B20_WriteByte(0xCC);
	DS18B20_WriteByte(0x44);
}

// 读取温度传感器返回的数据
float DS18B20_GetTemp()
{
    unsigned char byteL;
	unsigned char byteH;
	int temp;
	float T;
	DS18B20_Reset();
    // UART_SendString("start to read!\r\n");
    DS18B20_Delayus(100);  // 这里必须得有一个延时

	DS18B20_WriteByte(0xCC);
	DS18B20_WriteByte(0xBE);
	byteL = DS18B20_ReadByte();//低字节
	byteH = DS18B20_ReadByte();//高字节
	temp = (byteH << 8) | byteL;
	T = temp / 16.0;
	return T;
}


// float DS18B20_GetTemp(void)
// {
//     unsigned char data_[9], i, j;
//     int temp;
//     float value;

//     if(DS18B20_Reset()) { // 增加复位检测
//         UART_SendString("Reset Failed!\r\n");
//         return -999.9;
//     }
//     DS18B20_WriteByte(0xCC); // 跳过ROM
//     DS18B20_WriteByte(0x44); // 启动温度转换
    
//     // DS18B20_Delayms(750);

//     DS18B20_Reset();
//     DS18B20_WriteByte(0xCC); // 跳过ROM
//     DS18B20_WriteByte(0xBE); // 读取暂存器

//     // 读取暂存器时获取全部9字节数据
//     for(i=0; i<9; i++) {
//         data_[i] = DS18B20_ReadByte();
//     }

//     // 添加CRC校验
//     if(DS18B20_CRC8(data_, 8) != data_[8]) {
//         UART_SendString("CRC Error!\r\n");
//         // return -999.9;
//     }

//     // 更新温度数据获取方式
//     temp = (data_[1] << 8) | data_[0];
//     // 添加原始数据输出
//     UART_SendString("Raw Data: ");
//     for(j=0; j<9; j++) {
//         UART_SendHex(data_[j]);
//     }
//     UART_SendString("\r\n");

//     // value = temp * 0.0625;      // 转换温度值
//     value = temp / 16.0; // 转换温度值
//     return value;
// }

/**************** 新增CRC8校验函数 ****************/
// unsigned char DS18B20_CRC8(unsigned char *data_, unsigned char len)
// {
//     unsigned char crc = 0, i, j;
//     for(i=0; i<len; i++) {
//         crc ^= data_[i];
//         for(j=0; j<8; j++) {
//             if(crc & 0x01) crc = (crc >> 1) ^ 0x8C;
//             else crc >>= 1;
//         }
//     }
//     return crc;
// }